package com.common.baselibrary.mvp;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;

import com.common.baselibrary.R;

import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;

public class LoadingView extends View {

    private int viewDefaultSize;
    private int strokeColor;
    private int strokeWidth;
    private int backgroundStrokeColor;
    private Paint paint;
    private RectF drawArea;

    private float animationProgress;
    private int animationDuration;
    private float animationStepSize;
    private long lastDrawTimeMillis;


    public LoadingView(Context context) {
        this(context, null);
    }

    public LoadingView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }


    public LoadingView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        resolveAttributes(context, attrs);
        initializePaint();
    }

    private void resolveAttributes(Context context, @Nullable AttributeSet attrs) {
        strokeColor = ContextCompat.getColor(context, R.color.loadingViewDefaultStrokeColor);
        backgroundStrokeColor = ContextCompat.getColor(context, R.color.loadingViewDefaultBackgroundStrokeColor);
        strokeWidth = context.getResources().getDimensionPixelOffset(R.dimen.loadingViewDefaultStrokeWidth);
        viewDefaultSize = context.getResources().getDimensionPixelOffset(R.dimen.loadingViewDefaultSize);
        animationDuration = context.getResources().getInteger(R.integer.loadingViewDefaultDuration);
        if (attrs != null) {
            TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.LoadingView);
            strokeWidth = typedArray.getDimensionPixelOffset(R.styleable.LoadingView_ringStrokeWidth, strokeWidth);
            strokeColor = typedArray.getColor(R.styleable.LoadingView_ringStrokeColor, strokeColor);
            backgroundStrokeColor = typedArray.getColor(R.styleable.LoadingView_backgroundRingStrokeColor, backgroundStrokeColor);
            animationDuration = typedArray.getInt(R.styleable.LoadingView_animationDuration, animationDuration);
            typedArray.recycle();
        }
        animationStepSize = 1f / animationDuration;
    }

    public void setStrokeColor(int strokeColor) {
        this.strokeColor = strokeColor;
        invalidate();
    }

    private void initializePaint() {
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(strokeWidth);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        float topAndLeft = strokeWidth / 2f;
        drawArea = new RectF(topAndLeft, topAndLeft, getWidth() - topAndLeft, getHeight() - topAndLeft);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        boolean isWidthAtMost = widthMode == MeasureSpec.AT_MOST;
        boolean isHeightAtMost = heightMode == MeasureSpec.AT_MOST;
        if (isWidthAtMost && isHeightAtMost) {
            widthMeasureSpec = heightMeasureSpec = MeasureSpec.makeMeasureSpec(viewDefaultSize, MeasureSpec.EXACTLY);
        } else if (isWidthAtMost) {
            widthMeasureSpec = heightMeasureSpec;
        } else if (isHeightAtMost) {
            heightMeasureSpec = widthMeasureSpec;
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        float startAngle = 0f;
        float sweepAngle = 0f;
//        canvas.rotate(360f*progress,getWidth()/2f,getHeight()/2f);
        canvas.rotate(270f, getWidth() / 2f, getHeight() / 2f);
        if (animationProgress < .5f) {
            sweepAngle = animationProgress * 2f * 360f;
        } else {
            startAngle = (animationProgress - .5f) * 2f * 360f;
            sweepAngle = 360f - startAngle;
        }
        paint.setColor(backgroundStrokeColor);
        canvas.drawArc(drawArea, 0, 360, false, paint);
        paint.setColor(strokeColor);
        canvas.drawArc(drawArea, startAngle, sweepAngle, false, paint);

        long currentMillis = System.currentTimeMillis();
        float p = (currentMillis - lastDrawTimeMillis) * animationStepSize;
        animationProgress += p > 1f ? animationStepSize : p;
        if (animationProgress > 1f)
            animationProgress = 0;
        lastDrawTimeMillis = currentMillis;
        invalidate();
    }
}
